from flask import request, jsonify

from apps.apis import api
from apps.core.auth import verify_json_schema, verify_token_auth
from apps.core.database import db
from apps.core.schemaall import token_schema, update_user_schema, admin_user_schema
from apps.models import User
from apps.utils.return_info import ReturnInfo


@api.route("/admin/adduser", methods=['POST'])
@verify_json_schema(admin_user_schema)
@verify_token_auth(allowtokennull=False, namekey="ADMIN_USER")
# @verify_token_auth(allowtokennull=True)
def add_user():
    """
    添加用户接口
    ---
    tags:
      - admin
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          properties:
            username:
              type: string
              description: 用户名.
              example: Alice
            passwd:
              type: string
              description: 密码.
              example: Smith123
            ipaddr:
              type: string
              description: 限制用户的ip地址.
              example: 192.168.31.123
            token:
              type: string
              description: token. 用户认证.只用某个特殊的用户才能添加用户，暂时为用户 "admin"  密码 admin的用户
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    consumes:
      - application/json
    produces:
      - application/json
    definitions:
      ReturnInfoAddUser:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: object
            description: 返回的信息全部在data中获取
            properties:
              result:
                type: object
                properties:
                  username:
                    type: string
                    description: 添加的用户名
    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfoAddUser'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"成功","data":{"result": {"username":"Alice"}}}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"参数至少一个为空","data":{"ipaddr": "192.168.31.127","passwd": "","username": "Alice"}}
      405:
        description: 请求方式错误

    """
    ret_obj = ReturnInfo()
    jsons = request.json
    username = jsons.get("username")
    passwd = jsons.get("passwd")
    ipaddr = jsons.get("ipaddr")
    user = User.query.filter_by(username=username).first()
    if user:
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "user存在不能添加"
        return jsonify(ret_obj.todict())
    else:
        user = User(username=username, ip=ipaddr)
        if not user.passwd_rule(passwd):
            ret_obj.msg_code = "FAILED"
            ret_obj.msg = "密码不符合规则，必须包含数字、字母和一个特殊符号! @ # $ % ^ * ( ) ~ `{ } [ ] | & _"
            ret_obj.data = {"result": {"username": username}}
            return jsonify(ret_obj.todict())
        user.hash_password(passwd)
        db.session.add(user)
        db.session.commit()
        ret_obj.msg_code = "SUCCESS"
        ret_obj.msg = "添加成功"
        ret_obj.data = {"result": {"username": username}}
    return jsonify(ret_obj.todict())


@api.route("/admin/queryusers", methods=['POST'])
@verify_json_schema(token_schema)
@verify_token_auth(allowtokennull=False, namekey="ADMIN_USER")
def query_users():
    """
    查询用户
    ---
    tags:
      - admin
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          properties:
            token:
              type: string
              description: token. 用户认证.只用某个特殊的用户才能添加用户，暂时为用户 "admin"  密码 admin的用户
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    consumes:
      - application/json
    produces:
      - application/json
    definitions:
      ReturnInfoQUser:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: array
            description: 用户信息
            items:
              $ref: '#/definitions/QUser'
      QUser:
        type: object
        properties:
          username:
            type: string
            description: 用户名.
            example: Alice
          ipaddr:
            type: string
            description: 密码.
            example: '192.168.40.152'
          is_acitve:
            type: integer
            description: 1为活用户，0为死用户
            example: 1
    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfoQUser'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"成功","data":[{"ipaddr":"192.168.31.123","username":"a","is_acitve":1},{"ipaddr":"192.168.31.123","username":"b","is_acitve":0}]}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"json存在错误","data":{"result": jsons, "errors": errors}}
      405:
        description: 请求方式错误
    """
    ret_obj = ReturnInfo()
    userAll = User.query.all()
    ret_obj.msg_code = "SUCCESS"
    ret_obj.msg = "返回es可查询的字段的字典"
    listdata = []
    for user in userAll:
        dicts = {}
        ip = user.ip
        username = user.username
        dicts["ipaddr"] = ip
        dicts["username"] = username
        dicts["is_acitve"] = user.is_acitve
        listdata.append(dicts)
    ret_obj.data = listdata
    return jsonify(ret_obj.todict())


@api.route("/admin/updateuser", methods=['POST'])
@verify_json_schema(update_user_schema)
@verify_token_auth(allowtokennull=False, namekey="ADMIN_USER")
def update_user():
    """
    修改用户
    ---
    tags:
      - admin
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          properties:
            username:
              type: string
              description: 用户名.
              example: Alice
            passwd:
              type: string
              description: 密码.
              example: Smith123
            ipaddr:
              type: string
              description: 限制用户的ip地址.
              example: 192.168.31.123
            token:
              type: string
              description: token. 用户认证.只用某个特殊的用户才能添加用户，暂时为用户 "admin"  密码 admin的用户
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    consumes:
      - application/json
    produces:
      - application/json
    definitions:
      ReturnInfoUUser:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: object
            description: 返回的信息全部在data中获取
            properties:
              result:
                type: object
                properties:
                  username:
                    type: string
                    description: 添加的用户名
    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfoUUser'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"成功","data":{"result": {"username": "username"}}}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"json存在错误","data":{"result": jsons, "errors": errors}}
      405:
        description: 请求方式错误
    """
    ret_obj = ReturnInfo()
    jsons = request.json
    username = jsons.get("username")
    passwd = jsons.get("passwd")
    ipaddr = jsons.get("ipaddr")
    user = User.query.filter_by(username=username).first()
    if not user:
        ret_obj.msg = "用户不存在或密码错误"
        ret_obj.data = {"result": jsons}
        return jsonify(ret_obj.todict())
    user.hash_password(passwd)
    user.ip = ipaddr
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "无法插入数据库"
        ret_obj.data = {"errmsg": str(e)}
        return jsonify(ret_obj.todict())
    ret_obj.msg_code = "SUCCESS"
    ret_obj.msg = "修改密码成功"
    ret_obj.data = {"result": {"username": username}}
    return jsonify(ret_obj.todict())


@api.route("/admin/updateactive", methods=['POST'])
@verify_json_schema(update_user_schema)
@verify_token_auth(allowtokennull=False, namekey="ADMIN_USER")
def update_active():
    """
    更新用户状态删除用户和恢复
    ---
    tags:
      - admin
    parameters:
      - in: body
        name: body
        required: true
        description: JSON 参数.
        schema:
          properties:
            username:
              type: string
              description: 用户名.
              example: Alice
            is_active:
              type: integer
              description: 1为活用户，0为死用户
              example: 1
            token:
              type: string
              description: token. 用户认证.只用某个特殊的用户才能添加用户，暂时为用户 "admin"  密码 admin的用户
              example: eyJhbGciOiJIUzUxMiIsImlhdCI6MTU3Mjg0NzY3OSwiZXhwIjoxNTcyODQ4Mjc5fQ.eyJpZCI6MX0.rLbJ_6UQHuHoEA2xjbqtUa28Ogtf2I4JEDa0En0WjgB5pe5L1gT6F5L0RktZuJBE1lBEGT0TAJ1YC7PddwE-Cg
    consumes:
      - application/json
    produces:
      - application/json
    definitions:
      ReturnInfoUUser:
        type: object
        properties:
          msg_code:
            type: string
            description: SUCCESS 或者 FAILED.
            example: SUCCESS
          msg:
            type: string
            description: 说明文字，帮助找到失败原因
            example: 不能使用get请求
          data:
            type: object
            description: 返回的信息全部在data中获取
            properties:
              result:
                type: object
                properties:
                  username:
                    type: string
                    description: 添加的用户名
    responses:
      200:
        description: OK.
        schema:
          $ref: '#/definitions/ReturnInfoUUser'
        examples:
          returninfo: {"msg_code":"SUCCESS","msg":"成功","data":{"result": {"username": "username"}}}
      400:
        description: 上传数据有不符合规则,data中放入的是上传的数据.
        examples:
          returninfo: {"msg_code":"FAILED","msg":"json存在错误","data":{"result": jsons, "errors": errors}}
      405:
        description: 请求方式错误
    """
    ret_obj = ReturnInfo()
    jsons = request.json
    username = jsons.get("username")
    is_active = jsons.get("is_active")
    user = User.query.filter_by(username=username).first()
    if not user:
        ret_obj.msg = "用户不存在或密码错误"
        ret_obj.data = {"result": jsons}
        return jsonify(ret_obj.todict())
    user.is_acitve = is_active
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        ret_obj.msg_code = "FAILED"
        ret_obj.msg = "无法插入数据库"
        ret_obj.data = {"errmsg": str(e)}
        return jsonify(ret_obj.todict())
    ret_obj.msg_code = "SUCCESS"
    ret_obj.msg = "修改状态成功"
    ret_obj.data = {"result": {"username": username}}
    return jsonify(ret_obj.todict())
